package classes.pack;

import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.Timer;
import java.util.TimerTask;
import java.util.Vector;

import park.pack.R;

import com.google.android.maps.GeoPoint;
import com.google.android.maps.MapView;

import android.app.Notification;
import android.app.Service;
import android.content.Context;
import android.content.Intent;
import android.location.Criteria;
import android.location.GpsStatus;
import android.location.Location;
import android.location.LocationManager;
import android.os.Binder;
import android.os.Handler;
import android.os.IBinder;
import android.os.Looper;
import android.os.Message;
import android.util.Log;
import android.widget.Toast;
import java.lang.Object;

public class BackGroundService<protectionService> extends Service 
{	
	private static final long UPDATE_INTERVAL = 10000;	
	private Timer timer = new Timer();

	private Gps gps; 	
	//private Logging logging;
	private Vector<GeoLoc> geoLocs = new Vector<GeoLoc>();
	private Profiling profiling;

	private Handler handlerStart;
	private Handler handlerStop;
	private Thread loopThread;
	public static boolean stopService = true;
	
	public void onCreate()
	{		
		stopService = false;
		Log.i("Test-TIMER", "CREATED");			
		gps = new Gps(GeoLocType.GPS, Gui.getUiMain());
		gps.StartGps();
		createGeoLocs();
		
		handlerStart = new Handler()
		{
	        @Override	        
	        public void handleMessage(Message msg) 
	        {	            
	            super.handleMessage(msg);
	            Toast.makeText(BackGroundService.this, "Wilt u starten met parkeren?", Toast.LENGTH_SHORT).show();
	        }
	    };
	    handlerStop = new Handler()
		{
	        @Override	        
	        public void handleMessage(Message msg) 
	        {	            
	            super.handleMessage(msg);
	            Toast.makeText(BackGroundService.this, "Wilt u stoppen met parkeren?", Toast.LENGTH_SHORT).show();
	        }
	    };
	
		loopThread = new Thread()
	    {			
	        public void run() 
	        {	      
	        	/*
	        	try {
	        	    // preparing a looper on current thread
	        	    // the current thread is being detected implicitly
	        	    Looper.prepare();
	        	    Thread.sleep(10000);		
	        	    // now, the handler will automatically bind to the
	        	    // Looper that is attached to the current thread
	        	    // You don't need to specify the Looper explicitly
	        	    //handler = new Handler();
	        	    Gui.startParkingSequence();
	        	    // After the following line the thread will start
	        	    // running the message loop and will not normally
	        	    // exit the loop unless a problem happens or you
	        	    // quit() the looper (see below)
	        	    
	        	    Looper.loop();
	        	  } catch (Throwable t) {
	        	    Log.e("tag", "halted due to an error", t);
	        	  }
	        	*/
	        	
	        	
		        while(stopService==false)//!interrupted())
		        {
		           try 
		           {
		        	   Thread.sleep(10000);		
		        	   
		        	   //handler.sendEmptyMessage(0);	       
		           } 	
		           catch (InterruptedException e) 
		           {		            
		        	   e.printStackTrace();
		           } 
		           //handler.sendEmptyMessage(0);
		           Log.i("pos", gps.getCurrentPosition().toString());
		           parkingCheck();
		        }
		        
		        
	        }
	    };
	    loopThread.start();
	}
	
	
	public static boolean isRunning()
	{
		if(stopService == true)
		{
			return false;
		}
		else 
		{
			return true;
		}
	}
	
	public class MyBinder extends Binder 
	{
	    BackGroundService getService() 
	    {
		        return BackGroundService.this;
		}
	}
	
	//custom functions
	public GeoPoint GetCurrentPosition()
	{
		
		GeoLocType preferedType = Gui.getProfiling().getPreferedGeoLocType();		
			
		GeoLoc preferedGeoLoc = null;
		
		switch(preferedType)
		{
			case GPS:
				preferedGeoLoc = (Gps) this.getGeoLocByType(preferedType);
				break;
			default:
				//log ERR_6_4_1_ERR_INTERFACE_TYPE_UNKNOWN
				Log.e("Error", "6_4_1");
				break;
		}
		
		if(preferedGeoLoc != null)
		{
			Log.e("test", "before current pos");
			return preferedGeoLoc.getCurrentPosition();
		}
		else
		{
			// log ERR_6_2_1_NO_VALID_PREFERRED_INTERFACE 
			Log.e("Error", "6_2_1");
			
		}
		
		return null;

		
		//return new GeoPoint(20, 20);
	}
		
	

	/////////////////////
	////// GETTERS //////
	
	
	
	////// GETTERS //////
	/////////////////////
	
	////// SETTERS //////
	/////////////////////
	
	public void createGeoLocs()
	{
		//create all GeoLocs child classes and add them to geoLocs
		Log.i("BGS", "before");
		//create gps
		//LocationManager locationManager = (LocationManager) getSystemService(Context.LOCATION_SERVICE);
		
		
		
		//!!!!!crashes on gui
		geoLocs.add(gps);
		Log.i("BGS", "after");
		//create CellId
		
	}
	
	///////////////////////////////////////////////////////////////////////////////////////////
	
	//overrides////////////////////////////////////////////////////////////////////////////////
	
	
	@Override
	public void onDestroy() 
	{	
		gps.StopGps();		
		loopThread.interrupt();	
		Toast.makeText( getApplicationContext(), "Service Stopped", Toast.LENGTH_LONG).show();					
	}
	
	@Override
	public void onStart(Intent intent, int startid) 
	{		
		Toast.makeText( getApplicationContext(), "Service Started", Toast.LENGTH_LONG).show();
	}
	///////////////////////////////////////////////////////////////////////////////////////////////
	
		
	public GeoLoc getGeoLocByType(GeoLocType type)
	{
		//loop through interfaces
		for(int i = 0; i < this.geoLocs.size(); i++)
		{
			if(this.geoLocs.get(i).getGeoLocType() == type)
			{
				return this.geoLocs.get(i);
			}
		}		
		return null;		
	}

	@Override
	public IBinder onBind(Intent arg0) {
		// TODO Auto-generated method stub
		return null;
	}
	
	public void parkingCheck()
	{
		//this method checks whether or not the user should receive a start parking dialog
		//and starts a dialog if necessary
		//handler.sendEmptyMessage(0);
		
		Profile curProfile = Gui.getProfiling().GetCurrentProfile();
		//profiling.GetCurrentProfile();
		int day = new java.util.Date().getDay();
		boolean todayValid = false;
		switch(day)
		{
		case 1: 
			todayValid = curProfile.getMaandag();
			break;
		case 2:
			todayValid = curProfile.getDinsdag();
			break;
		case 3:
			todayValid = curProfile.getWoensdag();
			break;
		case 4:
			todayValid = curProfile.getDonderdag();
			break;
		case 5:
			todayValid = curProfile.getVrijdag();
			break;
		case 6:
			todayValid = curProfile.getZaterdag();
			break;
		case 7:
			todayValid = curProfile.getZondag();
			break;
		default:
			
			break;
		}
		Log.i("day",Integer.toString(day));
		
		if(todayValid == true)
		{
			checkStartParking();
			checkStopParking();
		}
		
		
	}
	
	public void checkStartParking()
	{
		//////
		//	if allowed to notify user (using day of the week)
		//	notify user
		//////
		
		if(Logging.getLatestStatus() != null)
		{
					
			
			Vector <LogRecord> lastLocations = Logging.getLoggedPositions(2);
			if(lastLocations.size() == 2 && (Logging.getLatestStatus() == AppStatus.NOT_PARKING) )
			{
				int parkingZone = -1;
				for(int i = 0; i < lastLocations.size(); i++)
				{
					if(ParkingZones.inParkingZone(lastLocations.get(i).getLocation()))
					{
						int tempParkZone = ParkingZones.getParkingZone(lastLocations.get(i).getLocation());
						
						if(tempParkZone == parkingZone)//&& nextTry > current time 
						{
							
							//Gui.startParkingSequence();//if start popup should be generated
							handlerStart.sendEmptyMessage(0);
							//if through checks, notify user
							//Gui.createToast("NOTIFY");
							
						}
					}
				}
			}
			
			if(isSpeedAboveUserLimit())
			{
				handlerStart.sendEmptyMessage(0);
			}
		}
		handlerStart.sendEmptyMessage(0);
		
	}
	public void checkStopParking()
	{
		
		if(isSpeedAboveUserLimit() && (Logging.getLatestStatus() == AppStatus.PARKING || Logging.getLatestStatus() == AppStatus.FREE_PARKING))
		{
			handlerStop.sendEmptyMessage(0);
		}
		

	}
	public boolean isSpeedAboveUserLimit()
	{
		double distance;  
		Location locationA = new Location("point A");  
		Location locationB = new Location("point B");
		
				
		if(Logging.getLoggedPositions(2).size() == 2)
		{
			LogRecord rec0 = Logging.getLoggedPositions(2).get(0);
			LogRecord rec1 = Logging.getLoggedPositions(2).get(1);
			
			
			locationA.setLatitude(rec0.getLocation().getLatitudeE6()/ 1e6);  
			locationA.setLongitude(rec0.getLocation().getLongitudeE6()/ 1e6);  		
			locationB.setLatitude(rec1.getLocation().getLatitudeE6()/ 1e6);  
			locationB.setLongitude(rec1.getLocation().getLongitudeE6()/ 1e6);  
						
			distance = locationA.distanceTo(locationB);
			String time0 = rec0.getDateTime();
			String time1 = rec1.getDateTime();
			
			
			
			long diff = 0;
			SimpleDateFormat  format0 = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");  
			SimpleDateFormat  format1 = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
			try {  
			    Date date0 = format0.parse(time0);  
			    Date date1 = format1.parse(time1); 
			    diff = date0.getTime() - date1.getTime();
			} catch (Exception e) {  

			    
			}

			
			
			if(diff > 0)
			{
				
				double dDiff = diff / 1000;
				Log.i("diff time", Double.toString(dDiff));//distance for testing
				Log.i("diff distance", Double.toString(distance));//distance for testing
				if(((distance / dDiff) / 3.6) > Gui.getProfiling().GetCurrentProfile().getSpeed())
				{
					return true;
				}				
			}			
			
		}
		return false;
		
	}
	
}
